(function ($) {
    $.fn.UserList = function (conn, chat) {
        var users = [];

        var self = this;
        var socket = conn;
        var chat = chat;

        this.onConnection = function (evt) {
            update(evt);
        }

        this.onConnectionLost = function (evt) {
            update(evt);
        }

        this.onRoomJoin = function (evt) {
            update(evt);
        }

        this.onUserExitRoom = function (evt) {
            //----------------------------------------------------------
            // REDUDANCY CHECK
            //----------------------------------------------------------
            // get SELF_UID from document DOM
            var uid = $(document).get(0).SELF_UID;

            if (evt.user.id == uid) {     // if this is myself in another tab/browser
                return;
            }

            update(evt);

            var content = $("#chatbox_" + evt.user.id + " .chatbox-content");
            if (content.length > 0) {
                content.append('<div class="chatbox-message">' +
					'<span class="notice">' + evt.user.username + 
                    ' has been left the room.</span></div>');
            }
        }

        this.onUserEnterRoom = function (evt) {
            //----------------------------------------------------------
            // REDUDANCY CHECK
            //----------------------------------------------------------
            // get SELF_UID from document DOM
            var uid = $(document).get(0).SELF_UID;

            if (evt.user.id == uid) {     // if this is myself in another tab/browser
                return;
            }

            update(evt);
        }

        function update(evt) {
            self.html('');
            var list = $('<ul>').appendTo(self);

            if (evt.room == null || typeof evt.room == "undefined") {
                return;
            }

            var users = evt.room.users; // list of users            
            for (var i = 0; i < users.length; i++) {
                var user = users[i];

                var entry = $('<li>').appendTo(list);
                $.extend(entry.get(0), { 'user': user });

                // get SELF_UID from document DOM
                var suid = $(document).get(0).SELF_UID;
                entry.append('<span class="nick">' + user.username + '</span>');

                if (suid != user.id) {
                    entry.click(function (e) {
                        privateChat(this.user);
                    });
                } else {
                    entry.addClass('self');
                }
            }
        }

        this.onPrivateMessage = function (evt) {
            var uid, uname, user;

            // get SELF_UID from document DOM
            var suid = $(document).get(0).SELF_UID;

            if (evt.sender.id == suid) {
                user = evt.recipient;
                uid = evt.recipient.id;
                uname = evt.recipient.username;
            } else {
                user = evt.sender;
                uid = evt.sender.id;
                uname = evt.sender.username;
            }

            var box = $("#chatbox_" + uid);
            if (box.length <= 0) {
                createChatBox(user);
            }

            if (box.css('display') == 'none') {
                box.css('display', 'block');
                restructureChatBoxes();
            }

            if (evt.sender.id == suid) {
                $("#chatbox_" + uid + " .chatbox-content").append('<div class="chatbox-message">' +
					'<span class="chatbox-info">' + evt.message + '</span></div>');
            } else {
                newMessages[uid] = true;
                newMessagesWin[uid] = true;
                $("#chatbox_" + uid + " .chatbox-content").append('<div class="chatbox-message">' +
				'<span class="from">' + uname + ':&nbsp;&nbsp;</span>' +
				'<span class="content">' + evt.message + '</span></div>');
            }

            $("#chatbox_" + uid + " .chatbox-content").scrollTop($("#chatbox_" +
                uid + " .chatbox-content")[0].scrollHeight);
        }

        // event notifies the result of a connection attempt.
        // event { 'type': connection, 'result': true/false[, evt] }
        socket.bind('connection', this.onConnection);

        // event notifies the disconnection from the Server.
        // event { 'type': connectionLost, 'reason': manual/kick/ban/unknown[, evt] }
        socket.bind('connectionLost', this.onConnectionLost);

        // event is fired whenever a User enters one of the Rooms where the current User is joined.
        // event { 'type': userEnterRoom, 'room': { 'id': id, 'name': name, 'users': users }, 
        // 'user': { 'id': id, 'name': name }[, evt] }
        socket.bind('userEnterRoom', this.onUserEnterRoom);

        // event is fired whenever a User leaves one of the Rooms where the current User is joined.
        // event { 'type': userExitRoom, 'room': { 'id': id, 'name': name, 'users': users }, 
        // 'user': { 'id': id, 'name': name }[, evt] }
        socket.bind('userExitRoom', this.onUserExitRoom);

        // event is dispatched in response to a login request.
        // event { 'type': roomJoin, 'room': { 'id': id, 'name': name, 'users': users }, 
        // 'user': { 'id': id, 'name': name }[, evt] }
        socket.bind('roomJoin', this.onRoomJoin);

        // event is fired when a User receives a private message.
        // event { 'type': privateMessage, 'room': { 'id': id, 'name': name }, 
        // 'message': message, 'sender': { 'name': name, 'id': id }[, evt] }
        socket.bind('privateMessage', this.onPrivateMessage);

        return this;
    }
})(jQuery);

